package com.example.snakegame.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Point
import android.util.AttributeSet
import android.util.Log
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import com.example.snakegame.utils.SoundManager
import java.util.Random
import kotlin.math.abs

class SnakeView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr), GestureDetector.OnGestureListener {
    companion object {
        private const val TAG = "SnakeView"
    }

    private val paint = Paint()
    private var cellSize = 0f
    private val snake = mutableListOf<Point>()
    private var food = Point(0, 0)
    private var direction = Direction.RIGHT
    private var isRunning = false
    private var score = 0

    private val gridSize = 20
    private val updateDelay = 150L // 蛇的移动速度

    var onGameOver: ((Int) -> Unit)? = null
    var onScoreChanged: ((Int) -> Unit)? = null

    private var isPaused = false

    private val gestureDetector: GestureDetector = GestureDetector(context, this)

    private val soundManager = SoundManager(context)

    init {
        paint.isAntiAlias = true
        resetGame()
    }

    override fun onDown(e: MotionEvent): Boolean = true

    override fun onShowPress(e: MotionEvent) {}

    override fun onSingleTapUp(e: MotionEvent): Boolean = false

    override fun onScroll(
        e1: MotionEvent?,
        e2: MotionEvent,
        distanceX: Float,
        distanceY: Float
    ): Boolean = false

    override fun onLongPress(e: MotionEvent) {}

    override fun onFling(
        e1: MotionEvent?,
        e2: MotionEvent,
        velocityX: Float,
        velocityY: Float
    ): Boolean {
        if (e1 == null) return false

        val dx = e2.x - e1.x
        val dy = e2.y - e1.y

        if (abs(dx) > abs(dy)) {
            // 水平方向滑动
            if (dx > 0) {
                setDirection(Direction.RIGHT)
            } else {
                setDirection(Direction.LEFT)
            }
        } else {
            // 垂直方向滑动
            if (dy > 0) {
                setDirection(Direction.DOWN)
            } else {
                setDirection(Direction.UP)
            }
        }
        return true
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        return gestureDetector.onTouchEvent(event) || super.onTouchEvent(event)
    }

    private fun resetGame() {
        snake.clear()
        snake.add(Point(gridSize / 2, gridSize / 2))
        generateFood()
        score = 0
        direction = Direction.RIGHT
        isRunning = true
        invalidate()
    }

    private fun generateFood() {
        val random = Random()
        do {
            food = Point(
                random.nextInt(gridSize),
                random.nextInt(gridSize)
            )
        } while (snake.contains(food))
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        cellSize = width.toFloat() / gridSize

        // 绘制蛇
        paint.color = Color.GREEN
        snake.forEach { point ->
            canvas.drawRect(
                point.x * cellSize,
                point.y * cellSize,
                (point.x + 1) * cellSize,
                (point.y + 1) * cellSize,
                paint
            )
        }

        // 绘制食物
        paint.color = Color.RED
        canvas.drawRect(
            food.x * cellSize,
            food.y * cellSize,
            (food.x + 1) * cellSize,
            (food.y + 1) * cellSize,
            paint
        )
    }

    fun updateGame() {
        if (!isRunning || isPaused) {
            Log.d(TAG, "Game not running or paused. isRunning: $isRunning, isPaused: $isPaused")
            return
        }

        val head = snake.first()
        val newHead = when (direction) {
            Direction.UP -> Point(head.x, head.y - 1)
            Direction.DOWN -> Point(head.x, head.y + 1)
            Direction.LEFT -> Point(head.x - 1, head.y)
            Direction.RIGHT -> Point(head.x + 1, head.y)
        }

        Log.d(TAG, "Snake moving to: ${newHead.x}, ${newHead.y}")

        // 检查碰撞
        if (newHead.x < 0 || newHead.x >= gridSize ||
            newHead.y < 0 || newHead.y >= gridSize ||
            snake.contains(newHead)
        ) {
            Log.d(TAG, "Collision detected!")
            handleGameOver()
            return
        }

        snake.add(0, newHead)

        if (newHead == food) {
            Log.d(TAG, "Food eaten! Score: $score")
            score += 10
            onScoreChanged?.invoke(score)
            generateFood()
            soundManager.playSound(SoundManager.SoundType.EAT)
        } else {
            snake.removeAt(snake.size - 1)
            soundManager.playSound(SoundManager.SoundType.MOVE)
        }

        invalidate()
    }

    fun setDirection(newDirection: Direction) {
        val isOpposite = when (newDirection) {
            Direction.UP -> direction == Direction.DOWN
            Direction.DOWN -> direction == Direction.UP
            Direction.LEFT -> direction == Direction.RIGHT
            Direction.RIGHT -> direction == Direction.LEFT
        }

        if (!isOpposite) {
            direction = newDirection
        }
    }

    fun togglePause() {
        isPaused = !isPaused
    }

    enum class Direction {
        UP, DOWN, LEFT, RIGHT
    }

    private fun handleGameOver() {
        isRunning = false
        soundManager.playSound(SoundManager.SoundType.GAME_OVER)
        onGameOver?.invoke(score)
    }

    fun releaseSoundManager() {
        soundManager.release()
    }
} 